package com.shinewind.home.controller;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import cn.hutool.core.util.*;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.shinewind.common.config.sms.properties.SmsClient;
import com.shinewind.common.constant.messageConstant;
import com.shinewind.common.util.RecommendUtils;
import com.shinewind.common.config.sms.config.SmsConfig;
import com.shinewind.home.service.*;
import com.shinewind.pojo.dto.RateDto;
import com.shinewind.pojo.entity.Brand;
import com.shinewind.pojo.entity.Model;
import com.shinewind.pojo.result.Result;
import com.shinewind.pojo.vo.NewProductsVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/index")
@Api(value = "首页模型接口", description = "用于实现首页模型列表的显示")
public class ModelController {
    @Autowired
    private IModelService iModelService;
    @Autowired
    private IStatusService iStatusService;
    @Autowired
    private IBrandService iBrandService;
    @Autowired
    private INewsService iNewsService;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private IRateService iRateService;
    @Autowired
    private IUserInfoMappingService iUserInfoMappingService;
    @Autowired
    private IModelMappingService iModelMappingService;
    @Autowired(required = false)
    @Qualifier("smsRequest")
    private SmsClient.Request smsRequest;
    @Autowired(required = false)
    @Qualifier("smsClient")
    private SmsClient smsClient;

    @GetMapping("/model/newProducts/list")
    @ApiOperation(value = "新品速递列表", notes = "使用ALS协同推荐算法", response = Result.class)
    public Result getNewProductsListByuId(@RequestParam(value = "uId",required = false) String uId) throws IOException {
        System.out.println("uId:"+uId);
        if(StrUtil.isNotBlank(uId)){
            /*//将评分表中的信息封装成列表
            List<Rating> ratings = iRateService.getAllRates();
            //创建dataCsv文件
            RecommendUtils.createDataCsv(ratings);
            //训练模型,为用户推荐10个模型
            RecommendUtils.createTestCsv(10);*/
            if(RecommendUtils.testCsvIsExist() == true){
                //查询该用户的id映射
                Integer userId= iUserInfoMappingService.getMappingUidByStrUid(uId);
                //读取返回的推荐信息map
                Map<Integer, List<Integer>> recommends = RecommendUtils.readTestCsv();
                List<Integer> recommendModelIds = recommends.get(userId);
                System.out.println("recommendModelIds:"+recommendModelIds);
                if(ObjectUtil.isNotNull(recommendModelIds)){
                    if(recommendModelIds.size() >= 10){
                        //将映射的模型id还原
                        List<Model> ModelList = iModelMappingService.getStrMidByMappingMid(recommendModelIds);
                        ModelList = RandomUtil.randomEleList(ModelList,9);
                        List<NewProductsVo> newProductsVoList = getNewProductsVo(ModelList);
                        return Result.success(newProductsVoList, BooleanUtil.isTrue(newProductsVoList.size() > 0),
                                messageConstant.QUERY_SUCCESS);
                    }
                    else{
                        System.out.println("随机查询1");
                        //随机查询model
                        List<Model> ModelList = iModelService.getRanDomModelList();
                        List<NewProductsVo> newProductsVoList = getNewProductsVo(ModelList);
                        return Result.success(newProductsVoList, BooleanUtil.isTrue(newProductsVoList.size() > 0),
                                messageConstant.QUERY_SUCCESS);
                    }
                }
                else{
                    System.out.println("随机查询2");
                    //随机查询model
                    List<Model> ModelList = iModelService.getRanDomModelList();
                    List<NewProductsVo> newProductsVoList = getNewProductsVo(ModelList);
                    return Result.success(newProductsVoList, BooleanUtil.isTrue(newProductsVoList.size() > 0),
                            messageConstant.QUERY_SUCCESS);
                }
            }
            else{
                System.out.println("随机查询3");
                //随机查询model
                List<Model> ModelList = iModelService.getRanDomModelList();
                List<NewProductsVo> newProductsVoList = getNewProductsVo(ModelList);
                return Result.success(newProductsVoList, BooleanUtil.isTrue(newProductsVoList.size() > 0),
                        messageConstant.QUERY_SUCCESS);
            }
        }
        else{
            System.out.println("随机查询4");
            //随机查询model
            List<Model> ModelList = iModelService.getRanDomModelList();
            List<NewProductsVo> newProductsVoList = getNewProductsVo(ModelList);
            return Result.success(newProductsVoList, BooleanUtil.isTrue(newProductsVoList.size() > 0),
                    messageConstant.QUERY_SUCCESS);
        }
    }
    private List<NewProductsVo> getNewProductsVo(List<Model> ModelList) {
        if (!ModelList.isEmpty()) {
            List<NewProductsVo> newProductsVoList = ModelList.stream().map(model -> {
                Optional<Model> modelOptional = Optional.of(model);
                //将model信息放入newProductsVo
                NewProductsVo newProductsVo = NewProductsVo.builder().build();
                BeanUtils.copyProperties(modelOptional.get(), newProductsVo);
                //按照模型id查询其状态[saleTime,status]
                List<String> statusList = iStatusService.getStatusInfoById(modelOptional.get().getMId());
                newProductsVo.setSaleTime(statusList);
                //按照品牌id查询其品牌[brand]
                Brand brand = iBrandService.getBrandInfoById(modelOptional.get().getBId());
                newProductsVo.setBrand(brand.getBrand());
                return newProductsVo;
            }).collect(Collectors.toList());
            return newProductsVoList;
        }
        return null;
    }

    //生成验证码
    @GetMapping("/model/captCha")
    @ApiOperation(value = "生成验证码", notes = "生成验证码", response = void.class)
    public void getCaptCha(HttpServletResponse resp) throws Exception {
        //生成验证码图片
        LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(120,32,5,15);
        lineCaptcha.setBackground(new Color(250,235,215));
        lineCaptcha.setFont(new Font("宋体",Font.BOLD,32));
        //如果存在，将旧验证码更新成新验证码
        redisTemplate.opsForValue().set("CaptCha",lineCaptcha.getCode());
        System.out.println("CaptCha:"+redisTemplate.opsForValue().get("CaptCha"));
        //设置浏览器输出为图片
        resp.setContentType("image/jpeg");
        //禁止浏览器缓存
        resp.setHeader("Pragma","No-cache");
        //输出到浏览器
        OutputStream outputStream = resp.getOutputStream();
        lineCaptcha.write(outputStream);
        outputStream.flush();
        outputStream.close();
    }

    //发送短信验证码
    @GetMapping("/model/SmscaptCha")
    @ApiOperation(value = "发送短信验证码", notes = "发送短信验证码", response = Result.class)
    public Result getSmsCaptCha(@RequestParam(value = "telePhone",required = false) String telePhone) throws Exception {
        System.out.println("tele:"+telePhone);

        if(redisTemplate.getExpire(telePhone) > 0){
            return Result.fail(false,messageConstant.MESSAGE_EXIST);
        }
        else{
            //如果时间到了，更新成新验证码
            String code = RandomUtil.randomNumbers(5);
            smsRequest.setBizContent("{\"mobile\":[\""+telePhone+"\"],\"type\":0,\"template_id\":\"ST_2022033000000003\"," +
                    "\"sign\":\"模玩家\",\"send_time\":\""+smsClient.getTimestamp()+"\",\"params\":{\"code\":\""+code+"\"}}");
            // 这里是json字符串，send_time 为空时可以为null, params 为空时可以为null,短信签名填写审核后的签名本身，不需要填写签名id
            smsRequest.setMethod("sms.message.send");
            System.out.println(smsClient.execute(smsRequest));
            Map<String,String> result = new ObjectMapper().readValue(smsRequest.getBizContent(),Map.class);
            System.out.println("result:"+result);
            redisTemplate.opsForValue().set(telePhone,code,5,TimeUnit.MINUTES);
            System.out.println("SmsCaptCha:"+redisTemplate.opsForValue().get(telePhone));
            return Result.success(true,messageConstant.MESSAGE_SUCCESS);
        }
    }

    @GetMapping("/model/typeId/{mId}")
    @ApiOperation(value = "查询模型的typeId", notes = "查询typeId", response = Result.class)
    public Result getModelTypeIdBymId(@PathVariable("mId") String mId) throws IOException {
        Model model = iModelService.getModelByMId(mId);
        return Result.success(model.getTypeId(), BooleanUtil.isTrue(model.getTypeId() > 0),
                messageConstant.QUERY_SUCCESS);
    }

    @PostMapping("/model/save/rate")
    @ApiOperation(value = "用户对商品评分",notes = "评分功能",response = Result.class)
    public Result saveRateByDto(@RequestBody RateDto rateDto){
        Boolean flag = iRateService.saveRateByDto(rateDto);
        if(flag)
            return Result.success(true,
                    messageConstant.INSERT_SUCCESS);
        else
            return Result.fail(false,messageConstant.INSERT_ERROR);
    }
}